package cn.cdeden.knowledge.service.impl;

import cn.cdeden.common.satoken.utils.LoginHelper;
import cn.cdeden.knowledge.domain.*;
import cn.cdeden.knowledge.domain.dto.*;
import cn.cdeden.knowledge.enums.TreeEnum;
import cn.cdeden.knowledge.enums.TreeTypeEnum;
import cn.cdeden.knowledge.service.*;
import cn.cdeden.system.api.RemoteDeptService;
import cn.cdeden.system.api.RemotePostService;
import cn.cdeden.system.api.RemoteRoleService;
import cn.cdeden.system.api.domain.vo.RemoteDeptVo;
import cn.cdeden.system.api.domain.vo.RemoteRoleVo;
import cn.cdeden.system.api.model.LoginUser;
import io.undertow.util.BadRequestException;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class FilesTreeServiceImpl implements FilesTreeService {

    private final PersonalFilesTreeService personalFilesTreeService;

    private final TeamFilesTreeService teamFilesTreeService;

    private final TeamRelevanceRoleService teamRelevanceRoleService;

    private final EnterpriseFilesTreeService enterpriseFilesTreeService;

    @DubboReference(check = false)
    private final RemoteDeptService remoteDeptService;

    @DubboReference(check = false)
    private final RemoteRoleService remoteRoleService;

    @DubboReference(check = false)
    private final RemotePostService remotePostService;



    @Override
    public List<TreeNodeDto> getParentTreeNodeAll(String id, String fileType) throws BadRequestException {
        List<TreeNodeDto> list = new ArrayList<>();
        switch (fileType) {
            case "0": {
                list = queryPersonalFiles(id);
                break;
            }
            case "1": {
                list = queryTeamFiles(id);
                break;
            }
            case "2": {
                list = queryEnterpriseFiles(id);
                break;
            }
            case "3": {
//                list = queryTeam02Files(id);
                break;
            }
        }
        Collections.reverse(list);
        return list;
    }

    @Override
    public TreeNodeDirectory getNewParentTreeNodeAll(TreeNodeParam query) throws BadRequestException {
        TreeEnum treeEnum = TreeEnum.find(query.getFileType());
        LoginUser user = LoginHelper.getLoginUser();
//        FileUserDto user = FileUserUtils.getUser();
        Long userId = user.getUserId();
        Long deptId = user.getDeptId();
        //调用远程方法查询部门、角色、岗位信息
        List<RemoteDeptVo> superiorAll1 = remoteDeptService.getSuperiorAll(deptId);
        List<Long> deptIds = superiorAll1.stream().map(RemoteDeptVo::getDeptId).collect(Collectors.toList());

        List<RemoteRoleVo> remoteRoleVos = remoteRoleService.selectUserRoleByUserId(userId);
        List<Long> roleIds = remoteRoleVos.stream().map(RemoteRoleVo::getRoleId).collect(Collectors.toList());

        List<Long> jobIds = remotePostService.getAllJobById(userId);


        //用户自身部门以及上级部门
//        List<Long> deptIds = superiorAll.stream().map(DeptDto::getId).collect(Collectors.toList());
//        List<Long> roleIds = user.getRoles().stream().map(RoleSmallDto::getId).collect(Collectors.toList());
//        List<Long> jobIds=user.getJobs().stream().map(JobSmallDto::getId).collect(Collectors.toList());
        List<String> sort = query.getSort();
        String treeId = query.getId();
//        Map<String, Object> map = new HashMap<>();
        TreeNodeDirectory map =new TreeNodeDirectory();

        Map<String, Object> pageMap = new HashMap<>();
//        pageMap.put("totalCount","0" );
//        pageMap.put("pageCount","0" );
        pageMap.put("size",query.getSize() );
        switch (treeEnum){
            case PERSONAL: {
                PersonalFilesTree oneTree = personalFilesTreeService.lambdaQuery()
                    .eq(PersonalFilesTree::getId, treeId)
                    .eq(PersonalFilesTree::getCreateId, userId)
                    .isNull(PersonalFilesTree::getDeleteId)
                    .one();
                if (oneTree == null) {
                    throw new BadRequestException("非法的编号或文件夹已被删除");
                }
                FilesTree filesTree = personalFilesTreeService.selectPersonalSuperiorFolder(treeId, String.valueOf(userId), sort);
                map.setTree(filesTree);
                int size = query.getSize();
                map.setList(pageMap);
                ArrayList<String> strings = new ArrayList<>(Arrays.asList(oneTree.getSuperiorsIds().split(",")));
                if (StringUtils.equals(oneTree.getType(), TreeTypeEnum.FOLDER.getType())) {
                    strings.add(treeId);
                    pageMap.put("page",1 );
                }else {
                    int i = personalFilesTreeService.selectByIdTreePageInfo(String.valueOf(userId), treeId, oneTree.getParentId(), size, sort);
                    pageMap.put("page",i );
                }
                List<PersonalFilesTree> list = personalFilesTreeService.lambdaQuery().in(strings.size() > 0, PersonalFilesTree::getId, strings).list();
                ArrayList<DataItem> dataItems = new ArrayList<>();
                for (PersonalFilesTree personalFilesTree : list) {
                    dataItems.add(new DataItem(personalFilesTree.getRealName(),personalFilesTree.getId().toString()));
                }
                map.setList(pageMap);
                map.setSuperior(dataItems);
                return map;
            }
            //TODO 后续添加团队跳转
            case TEAM: {
                TeamFilesTree oneTree = teamFilesTreeService.lambdaQuery()
                    .eq(TeamFilesTree::getId, treeId)
                    .isNull(TeamFilesTree::getDeleteId)
                    .one();
                if (oneTree == null) {
                    throw new BadRequestException("非法的编号或文件夹已被删除");
                }

                int size = query.getSize();
                List<DataItem> allParentId = teamFilesTreeService.getAllParentId(oneTree.getParentId());
                Collections.reverse(allParentId);
                if (StringUtils.equals(oneTree.getType(), TreeTypeEnum.FOLDER.getType())) {
                    TeamFilesTree byId = teamFilesTreeService.getById(treeId);
                    allParentId.add(new DataItem(byId.getRealName(),treeId));
                    pageMap.put("page", 1);
                }else {
                    List<TeamRelevanceRole> relevanceRole = teamRelevanceRoleService.getRelevanceRole(oneTree.getTeamId(), userId, null);
                    int i = teamFilesTreeService.selectByIdTreePageInfo(treeId, oneTree.getParentId(), size, sort,relevanceRole);
                    pageMap.put("page",i );
                }
                map.setList(pageMap);
                map.setSuperior(allParentId);
                return map;
            }
            case ENTERPRISE: {
                EnterpriseFilesTree oneTree = enterpriseFilesTreeService.lambdaQuery()
                    .eq(EnterpriseFilesTree::getId, treeId)
                    .isNull(EnterpriseFilesTree::getDeleteId)
                    .one();
                if (oneTree == null) {
                    throw new BadRequestException("非法的编号或文件夹已被删除");
                }

                int size = query.getSize();



                List<DataItem> allParentId = enterpriseFilesTreeService.getAllParentId(oneTree.getParentId());
                Collections.reverse(allParentId);
                if (StringUtils.equals(oneTree.getType(), TreeTypeEnum.FOLDER.getType())) {
                    EnterpriseFilesTree byId = enterpriseFilesTreeService.getById(treeId);
                    allParentId.add(new DataItem(byId.getRealName(),treeId));
                    pageMap.put("page", 1);
                }else {
                    //判断是否有admin权限
                    int i ;
                    if (LoginHelper.isSuperAdmin(userId)) {
                        i = enterpriseFilesTreeService.selectByIdTreePageInfo(String.valueOf(userId), deptIds,roleIds,jobIds,treeId, oneTree.getParentId(), size, sort,false);
                    } else {
                        i = enterpriseFilesTreeService.selectByIdTreePageInfo(String.valueOf(userId), deptIds,roleIds,jobIds,treeId, oneTree.getParentId(), size, sort,true);
                    }
                    pageMap.put("page", i);
//                    if (enterprisePermService.isAdmin(null)){
//                        i = enterpriseFilesTreeService.selectByIdTreePageInfo(String.valueOf(userId), deptIds,roleIds,jobIds,treeId, oneTree.getParentId(), size, sort,false);
//                    }else {
//                        i = enterpriseFilesTreeService.selectByIdTreePageInfo(String.valueOf(userId), deptIds,roleIds,jobIds,treeId, oneTree.getParentId(), size, sort,true);
//                    }
//                    pageMap.put("page", i);
                }
                map.setList(pageMap);
                map.setSuperior(allParentId);
                return map;
            }
            default:
                throw new RuntimeException("错误的获取文件父级目录");
        }

    }


    /**
     * @Description // 个人库
     **/
    private List<TreeNodeDto> queryPersonalFiles(String treeNodeId) throws BadRequestException {
        List<TreeNodeDto> list = new ArrayList<>();
        PersonalFilesTree personalFilesTree = personalFilesTreeService.getById(treeNodeId);
        if (personalFilesTree == null){
            throw new BadRequestException("文件已删除");
        }
        list.add(new TreeNodeDto(String.valueOf(personalFilesTree.getId()), personalFilesTree.getRealName()));
        String parentId = personalFilesTree.getParentId();
//                System.err.println("parentId------" + parentId);
        while (parentId != null &&  !parentId.contains(PersonalFilesTreeServiceImpl.ku) ) {
            PersonalFilesTree personalFilesTreeParent = personalFilesTreeService.getById(parentId);
            if (personalFilesTreeParent.getId() == 1) {
                break;
            }
            list.add(new TreeNodeDto(String.valueOf(personalFilesTreeParent.getId()), personalFilesTreeParent.getRealName()));
            parentId = personalFilesTreeParent.getParentId();
        }
        return list;
    }


    private List<TreeNodeDto> queryTeamFiles(String treeNodeId){
        List<TreeNodeDto> list = new ArrayList<>();
        TeamFilesTree teamFilesTree = teamFilesTreeService.getById(treeNodeId);
        if (teamFilesTree == null){
            throw new RuntimeException("文件已删除");
        }
        list.add(new TreeNodeDto(String.valueOf(teamFilesTree.getId()), teamFilesTree.getRealName()));
        String parentId = teamFilesTree.getParentId();

        while (parentId != null) {
            TeamFilesTree teamFilesTreeParent = teamFilesTreeService.getById(parentId);
            list.add(new TreeNodeDto(String.valueOf(teamFilesTreeParent.getId()), teamFilesTreeParent.getRealName()));
            if (teamFilesTreeParent.getParentId() == null) {
                break;
            }
            parentId = teamFilesTreeParent.getParentId();
        }
        return list;
    }

    private List<TreeNodeDto> queryEnterpriseFiles(String treeNodeId) throws BadRequestException {
        List<TreeNodeDto> list = new ArrayList<>();
        EnterpriseFilesTree enterpriseFilesTree = enterpriseFilesTreeService.getById(treeNodeId);
        if (enterpriseFilesTree == null){
            throw new BadRequestException("文件已删除");
        }
        list.add(new TreeNodeDto(String.valueOf(enterpriseFilesTree.getId()), enterpriseFilesTree.getRealName()));
        String parentId = enterpriseFilesTree.getParentId();

        while (parentId != null) {
            EnterpriseFilesTree enterpriseFilesTreeParent = enterpriseFilesTreeService.getById(parentId);
            list.add(new TreeNodeDto(String.valueOf(enterpriseFilesTreeParent.getId()), enterpriseFilesTreeParent.getRealName()));
            if (enterpriseFilesTreeParent.getParentId() == null) {
                break;
            }
            parentId = enterpriseFilesTreeParent.getParentId();
        }
        return list;
    }
}
